﻿#include "qtnotification.h"

#include <QMouseEvent>
#include <QPainter>
#include <QDebug>

#define MSGTIP_V_SPACE         5

QtNotification::QtNotification(QWidget *parent) : QObject(parent)
{
    m_parentRect = QRect(0, 0, 0, 0);
}

QtNotification::~QtNotification()
{
    foreach(QtNotifyItem *msg, m_msgTips)
    {
        if (NULL != msg){
            delete msg;
            msg = NULL;
        }
    }
}

void QtNotification::setNotification(const QString &msg, int type, int yoffset)
{
    QWidget *parent = qobject_cast<QWidget *>(this->parent());
    int nsize = m_msgTips.size();
    QtNotifyItem *msgTip = new QtNotifyItem(m_nMsgIndex, msg, type);
    msgTip->setParent(parent);
    connect(msgTip, SIGNAL(closed()), this, SLOT(slotItemlose()));
    int offset = nsize * (msgTip->height() + MSGTIP_V_SPACE) - yoffset;
    msgTip->showMessage(QPoint(m_parentRect.right(), m_parentRect.top() + offset));
    m_msgTips.insert(m_nMsgIndex, msgTip);
    m_nMsgIndex += 1;
}

void QtNotification::setParentRect(const QRect &_rect)
{
    m_parentRect = _rect;
}

void QtNotification::slotItemlose()
{
    QtNotifyItem *msgTip = qobject_cast<QtNotifyItem *>(this->sender());
    int id = msgTip->id();
    int yoffset = msgTip->height() + MSGTIP_V_SPACE;
    m_msgTips.remove(id);

    delete msgTip;
    msgTip = NULL;

    if (m_msgTips.isEmpty()) {
        m_nMsgIndex = 0;
    }

    foreach(QtNotifyItem *msg, m_msgTips)
    {
        if (msg->id() > id) {
            msg->updatePos(QPoint(msg->x(), msg->y() - yoffset));
        }
    }
}

////////////////////////////////////////////////////////////////////
QtNotifyItem::QtNotifyItem(int id, const QString &_msg, const int &_type) :
    m_id(id), m_strMsg(_msg), m_msgType(_type)
{
    this->setFixedSize(320, 50);
    this->setMouseTracking(true);
#if 0
    // 当不设置父窗体作为背景时需要设置以下属性
    this->setWindowFlags(Qt::FramelessWindowHint | Qt::Tool | Qt::WindowStaysOnTopHint);
#endif

    m_animation = new QPropertyAnimation(this, "");
    m_animation->setDuration(200);
    connect(m_animation, SIGNAL(valueChanged(QVariant)), this, SLOT(onValueChanged(QVariant)));

    m_timer.setSingleShot(true);
    m_timer.setInterval(5000);
    connect(&m_timer, SIGNAL(timeout()), this, SIGNAL(closed()));

    m_pixmap.load(":/res/msgtip/ic_info.png");
    m_pixmapClose.load(":/res/msgtip/ic_close.png");

    if (MsgOk == _type) {
        m_pixmap.load(":/res/msgtip/ic_ok.png");
    } else if (MsgWarin == _type) {
        m_pixmap.load(":/res/msgtip/ic_warn.png");
    } else if (MsgError == _type) {
        m_pixmap.load(":/res/msgtip/ic_error.png");
    }
}

QtNotifyItem::~QtNotifyItem()
{
    m_animation->stop();
    delete m_animation;
    m_animation = NULL;
}

void QtNotifyItem::showMessage(const QPoint &pos)
{
    this->show();
    m_animation->setStartValue(QPoint(pos.x(), pos.y()));
    m_animation->setEndValue(QPoint(pos.x() - this->width(), pos.y()));
    m_animation->start();
    m_timer.start();
}

void QtNotifyItem::updatePos(const QPoint &pos)
{
    m_animation->setStartValue(this->pos());
    m_animation->setEndValue(pos);
    m_animation->start();
}

void QtNotifyItem::setMessage(const QString &_msg)
{
    m_strMsg = _msg;
    this->update();
}

int QtNotifyItem::id() const
{
    return m_id;
}

void QtNotifyItem::paintEvent(QPaintEvent *)
{
    QPainter painter(this);
    painter.setRenderHint(QPainter::Antialiasing);
    painter.setPen(QColor("#e6e8f1"));
    painter.setBrush(QColor("#ffffff"));
    painter.drawRoundedRect(1, 1, this->width() - 2, this->height() - 2, 5, 5);

    int yoffset = (this->height() - m_pixmap.height()) / 2;
    QRect rectIcon(10, yoffset, m_pixmap.width(), m_pixmap.height());
    painter.drawPixmap(rectIcon, m_pixmap);
    painter.setPen(QColor("#000000"));
    QRect rectContent = QRect(rectIcon.right() + 10, 1, this->width() - 80, this->height() - 2);
#if 1
    painter.drawText(rectContent, Qt::AlignLeft | Qt::AlignVCenter, m_strMsg);
#else
    painter.drawText(rectContent, Qt::AlignCenter, m_strMsg);
#endif

    painter.drawPixmap(m_btnClose.center().x() - 12, m_btnClose.center().y() - 12, m_pixmapClose);
}

void QtNotifyItem::mousePressEvent(QMouseEvent *e)
{
    if (m_btnClose.contains(e->pos())) {
        emit closed();
    }
}

void QtNotifyItem::mouseMoveEvent(QMouseEvent *e)
{
    this->setCursor(m_btnClose.contains(e->pos()) ? Qt::PointingHandCursor : Qt::ArrowCursor);
}

QSize QtNotifyItem::sizeHint() const
{
    return QSize(320, 50);
}

void QtNotifyItem::resizeEvent(QResizeEvent *e)
{
    int w = m_pixmapClose.width();
    int h = m_pixmapClose.height();
    m_btnClose = QRect(this->width() - w - 10, (this->height() - h) / 2, w, h);
    QWidget::resizeEvent(e);
}

void QtNotifyItem::onValueChanged(const QVariant &value)
{
    QPoint pos = value.toPoint();
    this->move(pos);
}
